package com.johnny.xia.game;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import com.johnny.xia.util.base.ValidatorUtil;

public class ShuihuUtil extends ShuihuTest{

    private static final Logger logger = LoggerFactory.getLogger(ShuihuUtil.class);
    
    private static int all; 
    
    static String[] n ={"1","2","3","4","5","6","7","8","9"};  
    static List<String> lineStrs = Arrays.asList(n);  
    
    public static List<Integer> str2List(String t){
        List<Integer> list = new ArrayList<>(t.length());
        
        for(int i=0;i<t.length();i++){
            list.add(Integer.parseInt(String.valueOf(t.charAt(i))));
        }
        return list;
    }
    
    @Test
    public void createLine(){
        all = 0;
        List<String> result = new ArrayList<>();
        int count = 3;
        take("",count,lineStrs,result);  
        
        for(String s : result){
            str2List(s);
        }
    }
    
    /**获取哪几条的情况*/
    public List<Integer> getLine(int lineCount){
        List<Integer> list = new ArrayList<>();
        return list;
    }
    
    public static void take(String s, int total, List<String> lst,List<String> result) {  
        for (int i = 0; i < lst.size(); i++) {  
            //System.out.println("i="+i);  
            List<String> templst=new LinkedList<String>(lst);  
            String n =  (String) templst.remove(i);// 取出来的数字  
            String str = s + n;  
            if (total == 1) { 
//                System.out.println(str);//以最极端 n个里面只取一个，直接把取出来的结果输出即可  
                all++;  
                result.add(str);
            } else {  
                int temp=total-1;//在同一层中total总量不能减,不能再原有变量的基础上  
                take(str, temp, templst,result);// 这里的temp以及templst都是全新的变量和集合  
            }  
        }  
    }
    
    @Test
    public void finalCreateData(){
        
        for(int i=0;i<1;i++){
            
//            card:3,lineNum:4|card:8,lineNum:3|card:8,lineNum:4|card:8,lineNum:4
            
            StopWatch watch = new StopWatch();
            watch.start("create data");
            List<PrizeLineControl> controls = new ArrayList<>();
            controls.add(new PrizeLineControl(1, 4, 3, 1));
            controls.add(new PrizeLineControl(1, 3, 8, 2));
            controls.add(new PrizeLineControl(1, 4, 8, 1));
            controls.add(new PrizeLineControl(1, 4, 8, 2));
            createData3(controls);
            watch.stop();
            System.out.println(watch.toString());
        }
        
       
        
    }
    
    public static int[][] createData3(List<PrizeLineControl> controls){
        
        int[][] data =null;
//        List<PrizeLineControl> controls = new ArrayList<>();
        
        //TODO 如果有万能牌就，放牌的列表就不要有万能牌了。
        boolean removeBoss = false;
        
//        controls.add(new PrizeLineControl(1, 3, 9, 1));
//        controls.add(new PrizeLineControl(2, 3, 2, 1));
//        controls.add(new PrizeLineControl(3, 3, 4, 1));

        Map<Integer, PrizeLineControl> controlMap = new HashMap<>();
        
        //9条线中，所有count条的情况
        List<String> result = new ArrayList<>();
        int count = controls.size();
        Collections.shuffle(lineStrs);
//        Collections.shuffle(cardList);
        take("",count,lineStrs,result);
        
        int removeCount = 0;

        for(String s : result){
            
            controlMap.clear();
            
            data = new int[3][5];
            
            List<Integer> lines =  str2List(s);
            
//            StringBuffer buf = new StringBuffer();
//            for(Integer i : lines){
//                buf.append(i+",");
//            }
            
//            System.out.println(buf.toString());
            
            removeBoss= initData(controls, data, controlMap,lines);
            
            if(removeBoss && removeCount == 0){
                for(int i=0;i<cardList.size();i++){
                    if(cardList.get(i)==9){
                        cardList.remove(i);
                    }
                }
                removeCount ++;
            }
            
            for(ShuihuData point : allPoint){
                //这个点有哪些线经过
                List<Integer> rline = pointLine.get(point.getX()+""+point.getY());
                
                
                if(data[point.getX()][point.getY()] != 0){
                    continue;
                }
                boolean tag = true;
                boolean chanage = false;
                
                for(int card : cardList){
                    for(int line : rline){
                    Collections.shuffle(cardList);
                        if(data[point.getX()][point.getY()] == 0){
                            data[point.getX()][point.getY()] = card;
                            chanage = true;
                        }
                        List<ShuihuData> lineData = lineMap.get(line);
                        List<ShuihuLineData> linePrize = checkSinglePrize(data, lineData);
                        
                        PrizeLineControl con = controlMap.get(line);

                        if (con == null && ValidatorUtil.isNotNullOrEmpty(linePrize)){
                            tag = false;
                            if(chanage){
                                data[point.getX()][point.getY()] = 0;
                            }
                            break;
                        }

                        if (con != null && ValidatorUtil.isNullOrEmpty(linePrize)){
                            tag = false;
                            if(chanage){
                                data[point.getX()][point.getY()] = 0;
                            }
                            break;
                        }

                        if (con != null && ValidatorUtil.isNotNullOrEmpty(linePrize)){
                            //TODO 需要判断3连，4连水浒的情况，如果是3连或者4连水浒，必定存在一个4连的其他牌，和5连的其他牌
                            ShuihuLineData prize = linePrize.get(0);
                            
                            if(con.getCard() != 9){
                                if (con.getCard() != prize.getCardData() || con.getLineNum() != prize.getLineNum() || linePrize.size() > 1){
                                    tag = false;
                                    if(chanage){
                                        data[point.getX()][point.getY()] = 0;
                                    }
                                    break;
                                }    
                            }else{
                                if (con.getCard() != prize.getCardData() || con.getLineNum() != prize.getLineNum() || linePrize.size() > 2){
                                    tag = false;
                                    if(chanage){
                                        data[point.getX()][point.getY()] = 0;
                                    }
                                    break;
                                }    
                            }
                        }
                    }
                    if(tag){
                        break;
                    }
                }
            }
            
            boolean t = checkData(data);
            
            LinkedHashMap<Integer,List<ShuihuLineData>> lineMap = checkLineInfo(data);
            
            if(lineMap == null || lineMap.size() != controls.size()){
                t = false;
            }else{
                boolean error = false;
                for(Map.Entry<Integer,List<ShuihuLineData>> entry : lineMap.entrySet()){
                    List<ShuihuLineData> _datas = entry.getValue();
                    PrizeLineControl control = controlMap.get(entry.getKey());
                    if((ValidatorUtil.isNotNullOrEmpty(_datas) && control == null)
                                    ||(ValidatorUtil.isNullOrEmpty(_datas) && control != null)){
                        t = false;
                        error = true;
                        break;
                    }else {
                        for(ShuihuLineData d : _datas){
                            if(d.getCardData() != control.getCard() || d.getLineNum() != control.getLineNum()){
                                t = false;
                                error = true;
                                break;
                            }
                        } 
                    }
                    
                    if(error){
                        break;
                    }
                }
                
            }
            
            if(t){
//                printCardData2(data);
                printResult(data);
                return data;
            }else{
//                printCardData2(data);
            }
            
        }
        return null;
    }
    
    @Test
    public void createData2(){

        List<Integer> lineListTmp = new ArrayList<>(lineList);
        
        int[][] data =null;
        List<PrizeLineControl> controls = new ArrayList<>();
        
        //TODO 如果有万能牌就，放牌的列表就不要有万能牌了。
        boolean removeBoss = false;
        
        controls.add(new PrizeLineControl(1, 3, 2, 1));
//        controls.add(new PrizeLineControl(2, 3, 2, 1));

        Map<Integer, PrizeLineControl> controlMap = new HashMap<>();
        
        //9条线中，所有count条的情况
        List<String> result = new ArrayList<>();
        int count = 1;
//        Collections.shuffle(lineStrs);
        take("",count,lineStrs,result);
        
        int removeCount = 0;

        for(String s : result){
            
            controlMap.clear();
            
            data = new int[3][5];
            
            List<Integer> lines =  str2List(s);
            
            StringBuffer buf = new StringBuffer();
            for(Integer i : lines){
                buf.append(i+",");
            }
            
            System.out.println(buf.toString());
            
            removeBoss= initData(controls, data, controlMap,lines);
            
            if(removeBoss && removeCount == 0){
                cardList.remove(8);
                removeCount ++;
            }
            
            for(ShuihuData point : allPoint){
                //这个点有哪些线经过
                List<Integer> rline = pointLine.get(point.getX()+""+point.getY());
                
                
                if(data[point.getX()][point.getY()] != 0){
                    continue;
                }
                
                for(int line : rline){
//                    Collections.shuffle(cardList);
                    boolean tag = true;
                    boolean chanage = false;
                    for(int card : cardList){
                        tag = true;
                        chanage = false;
                        if(data[point.getX()][point.getY()] == 0){
                            data[point.getX()][point.getY()] = card;
                            chanage = true;
                        }
                    
                   
                        List<ShuihuData> lineData = lineMap.get(line);
                        List<ShuihuLineData> linePrize = checkSinglePrize(data, lineData);
                        
                        PrizeLineControl con = controlMap.get(line);

                        if (con == null && ValidatorUtil.isNotNullOrEmpty(linePrize)){
                            tag = false;
                            if(chanage){
                                data[point.getX()][point.getY()] = 0;
                            }
                            continue;
                        }

                        if (con != null && ValidatorUtil.isNullOrEmpty(linePrize)){
                            tag = false;
                            if(chanage){
                                data[point.getX()][point.getY()] = 0;
                            }
                            continue;
                        }

                        if (con != null && ValidatorUtil.isNotNullOrEmpty(linePrize)){
                            //TODO 需要判断3连，4连水浒的情况，如果是3连或者4连水浒，必定存在一个4连的其他牌，和5连的其他牌
                            ShuihuLineData prize = linePrize.get(0);
                            
                            if(con.getCard() != 9){
                                if (con.getCard() != prize.getCardData() || con.getLineNum() != prize.getLineNum() || linePrize.size() > 1){
                                    tag = false;
                                    if(chanage){
                                        data[point.getX()][point.getY()] = 0;
                                    }
                                    continue;
                                }    
                            }else{
                                if (con.getCard() != prize.getCardData() || con.getLineNum() != prize.getLineNum() || linePrize.size() > 2){
                                    tag = false;
                                    if(chanage){
                                        data[point.getX()][point.getY()] = 0;
                                    }
                                    continue;
                                }    
                            }
                            
                            
                        }
                        
                        if(tag){
                            break;
                        }
                        
                    }
                    if(!tag){
                        if(chanage){
                            data[point.getX()][point.getY()] = 0;
                        }
                    }
//                    if(tag){
//                        break;
//                    }else{
//                        if(chanage){
//                            data[point.getX()][point.getY()] = 0;
//                        }
//                    }
                    
                    
                }
            }
            
            boolean t = checkData(data);
            
            if(t){
                printCardData2(data);
                printResult(data);
//                return;
            }else{
                printCardData2(data);
            }
            
        }
    
        
    }

    @Test
    public void createDate(){
        List<Integer> lineListTmp = new ArrayList<>(lineList);
        
        int[][] data =null;
        List<PrizeLineControl> controls = new ArrayList<>();
        
        //TODO 如果有万能牌就，放牌的列表就不要有万能牌了。
        boolean removeBoss = false;
        
        controls.add(new PrizeLineControl(1, 3, 2, 1));
//        controls.add(new PrizeLineControl(2, 3, 2, 1));

        Map<Integer, PrizeLineControl> controlMap = new HashMap<>();
        
        //9条线中，所有count条的情况
        List<String> result = new ArrayList<>();
        int count = 1;
//        Collections.shuffle(lineStrs);
        take("",count,lineStrs,result);
        
        int removeCount = 0;

        for(String s : result){
            
            data = new int[3][5];
            
            List<Integer> lines =  str2List(s);
            
            StringBuffer buf = new StringBuffer();
            for(Integer i : lines){
                buf.append(i+",");
            }
            
            System.out.println(buf.toString());
            
            removeBoss= initData(controls, data, controlMap,lines);
            
            if(removeBoss && removeCount == 0){
                cardList.remove(8);
                removeCount ++;
            }
            
            Collections.shuffle(cardList);
            
            for(ShuihuData point : allPoint){
                //这个点有哪些线经过
                List<Integer> rline = pointLine.get(point.getX()+""+point.getY());
                
                
                if(data[point.getX()][point.getY()] != 0){
                    continue;
                }
                
                for(int card : cardList){
                    boolean tag = true;
                    boolean chanage = false;
                    if(data[point.getX()][point.getY()] == 0){
                        data[point.getX()][point.getY()] = card;
                        chanage = true;
                    }
                    
                    for(int line : rline){
                        List<ShuihuData> lineData = lineMap.get(line);
                        List<ShuihuLineData> linePrize = checkSinglePrize(data, lineData);
                        
                        PrizeLineControl con = controlMap.get(line);

                        if (con == null && ValidatorUtil.isNotNullOrEmpty(linePrize)){
                            tag = false;
                            break;
                        }

                        if (con != null && ValidatorUtil.isNullOrEmpty(linePrize)){
                            tag = false;
                            break;
                        }

                        if (con != null && ValidatorUtil.isNotNullOrEmpty(linePrize)){
                            //TODO 需要判断3连，4连水浒的情况，如果是3连或者4连水浒，必定存在一个4连的其他牌，和5连的其他牌
                            ShuihuLineData prize = linePrize.get(0);
                            if (con.getCard() != prize.getCardData() || con.getLineNum() != prize.getLineNum()){
                                tag = false;
                                break;
                            }
                        }
                    }
                    if(tag){
                        break;
                    }else{
                        if(chanage){
                            data[point.getX()][point.getY()] = 0;
                        }
                    }
                }
            }
            
            boolean t = checkData(data);
            
            if(t){
                printCardData2(data);
                printResult(data);
//                return;
            }else{
//                printCardData2(data);
            }
            
        }
    }

    private static boolean initData(List<PrizeLineControl> controls,
                    int[][] data,
                    Map<Integer, PrizeLineControl> controlMap,
                    List<Integer> lines){

        Map<String, ShuihuData> map = new HashMap<>();
        Map<String, ShuihuData> publicData = new HashMap<>();
        for (Integer i : lines){
            List<ShuihuData> datas = lineMap.get(i);
            for (ShuihuData d : datas){
                if (map.get(d.getX() + "" + d.getY()) != null){
                    publicData.put(d.getX() + "" + d.getY(), d);
                }else{
                    map.put(d.getX() + "" + d.getY(), d);
                }
            }
        }
        
        boolean tag = false;

        int count=0;
        //设置公共点为水浒
        for (Map.Entry<String, ShuihuData> publicEntry : publicData.entrySet()){
            ShuihuData d = publicEntry.getValue();
            if(count < 2){
                data[d.getX()][d.getY()] = 9;
                tag = true;
                count++;
            }
            
        }

        for (int j = 0; j < controls.size(); j++){
            PrizeLineControl control = controls.get(j);
            int line = lines.get(j);
            List<ShuihuData> lineData = lineMap.get(line);
            ShuihuData d = null;
            if (control.getStartType() == 1){
                for (int i = 0; i < control.getLineNum(); i++){
                    d = lineData.get(i);
                    if (data[d.getX()][d.getY()] == 0){
                        data[d.getX()][d.getY()] = control.getCard();
                    }
                }
            }else{
                for (int i = lineData.size() - 1; i >= 5 - control.getLineNum(); i--){
                    d = lineData.get(i);
                    if (data[d.getX()][d.getY()] == 0){
                        data[d.getX()][d.getY()] = control.getCard();
                    }
                }
            }
            controlMap.put(line, control);
        }

        //        for (PrizeLineControl control : controls){
        //            for (Map.Entry<Integer, List<ShuihuData>> entry : lineMap.entrySet()){
        //                if (entry.getKey() == control.getLine()){
        //                    List<ShuihuData> lineData = lineMap.get(control.getLine());
        //                    ShuihuData d = null;
        //                    if (control.getStartType() == 1){
        //                        for (int i = 0; i < control.getLineNum(); i++){
        //                            d = lineData.get(i);
        //                            data[d.getX()][d.getY()] = control.getCard();
        //                        }
        //                    }else{
        //                        for (int i = lineData.size() - 1; i >= 5 - control.getLineNum(); i--){
        //                            d = lineData.get(i);
        //                            data[d.getX()][d.getY()] = control.getCard();
        //                        }
        //                    }
        //                }
        //            }
        //            controlMap.put(control.getLine(), control);
        //        }
        
        return tag;
    }

}
